package com.noticestation.collector;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Elements;
import nu.xom.ParsingException;
import nu.xom.ValidityException;

import org.apache.log4j.Logger;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;

import com.noticestation.domain.BasicEvent;

/*
 * Parse Basic Event xml file and return list of events
 * we rely on the XOM XML parser for the XML handling
 * 
 * @author Matthew Phillips
 * 
 * @return ArrayList of BasicEvent objects
 */
public class BasicEventCollector implements CollectorInterface, MessageSourceAware
{
	static Logger log = Logger.getLogger("BasicEventCollector");
	private MessageSource messageSource;

	/**
	 * Parses an events xml file and looks for events that occur in the next
	 * x hours
	 * 
	 * @return an arraylist of events
	 * @see com.noticestation.collector.CollectorInterface#findEvents()
	 */
	public ArrayList<BasicEvent> findEvents()
	{
		ArrayList<BasicEvent> list = new ArrayList<BasicEvent>();

		Builder builder = new Builder();

		try
		{
			Document doc = builder.build(messageSource.getMessage("pathToXMLFile", null, null));
			// events should match doc root, the events element
			Element eventRoot = doc.getRootElement();

			// eventChildren should be all event elements
			Elements events = eventRoot.getChildElements("event");

			String dateString = "";
			String dateFormatString = messageSource.getMessage("dateFormat", null, null);
			SimpleDateFormat format = new SimpleDateFormat(dateFormatString);
			Date date;
			Date now;
			long timeDiff;
			long numHoursUntilEvent;

			// loop through events looking for events that occur in the next 24 hours
			for (int i = 0; i < events.size(); i++) {

				dateString = events.get(i).getFirstChildElement("date").getValue();
				date = format.parse(dateString);
				now = new Date();
				// Get time difference, and divide by one hour
				timeDiff = date.getTime() - now.getTime(); 
				numHoursUntilEvent = timeDiff/(1000L  * 60L * 60L);

				String hoursOfNotice = messageSource.getMessage("hoursOfNotice", null, null);

				// If the event occurs in the next 24 hours, add it to the list
				if (numHoursUntilEvent > 0 && numHoursUntilEvent < Long.valueOf(hoursOfNotice))
				{
					BasicEvent basicEvent = new BasicEvent();
					basicEvent.setName(events.get(i).getFirstChildElement("name").getValue());
					basicEvent.setDate(dateString);
					basicEvent.setDistrict(events.get(i).getFirstChildElement("district").getValue());
					list.add(basicEvent);
				}
			}
		}
		catch (ValidityException e)
		{
			log.error("XML is not valid, " + e);
			System.exit(0);
		}
		catch (ParsingException e)
		{
			log.error("Unable to parse XML, " + e);
			System.exit(0);
		}
		catch (IOException e)
		{
			log.error("Unable to locate XML file, " + e);
			System.exit(0);
		}
		catch (ParseException e)
		{
			log.error("Date seems to be an unexpected format. Please ensure that date set in properties file matches date in events file." + e);
		}

		return list;
	}

	/**
	 * Spring's message source aware allows for sharing of messages (most
	 * likely used like a properties file)
	 * 
	 * @see org.springframework.context.MessageSourceAware#setMessageSource(org.springframework.context.MessageSource)
	 */
	public void setMessageSource(MessageSource messageSourece)
	{
		this.messageSource = messageSourece;		
	}
}
